//--------------------------------------------------------------------------------------//
//                                                                                      //
//    __  __  __    __    __  ___   __   ___  __    ___    __  __  __  ___  ___  __     //
//   / _)/  \(  )  (  )  (  )(   \ (  ) (  ,)(  )  (  _)  (  \/  )/  \(   \(  _)(  )    //
//  ( (_( () ))(__  )(__  )(  ) ) )/__\  ) ,\ )(__  ) _)   )    (( () )) ) )) _) )(__   //
//   \__)\__/(____)(____)(__)(___/(_)(_)(___/(____)(___)  (_/\/\_)\__/(___/(___)(____)  //
//                                                                                      //
//                                                                                      //
//       Copyright by Theodor Mader, 2009                                               //
//			www.theomader.com/public/Projects.html                                      //
//--------------------------------------------------------------------------------------//

#ifndef __GEOMETRY_H_INCLUDED__
#define __GEOMETRY_H_INCLUDED__

#include <vector>
#include <functional>

extern "C"
{
	__declspec(dllexport) 
		void ComputeBiggestEigenvector( double* matrix, double& x, double& y, double& z );
}

namespace Geometry
{
	struct Vertex
	{
		float x, y, z;
		Vertex() : x(0.0f), y(0.0f), z(0.0f) {}
		Vertex( float xx, float yy, float zz ) : x(xx), y(yy), z(zz) {}

		Vertex operator+( const Vertex& other ) const;
		Vertex operator-( const Vertex& other ) const;
		Vertex operator*( float scale ) const;
		Vertex& operator+=( const Vertex& other );
		Vertex& operator/=( const float c );
		bool operator<( const Vertex& other ) const;
	};

	struct Plane
	{
		float x, y, z, d;

		Plane() : x( 0.0f ), y( 0.0f ), z( 0.0f ), d( 0.0f ) {}
		Plane( float xx, float yy, float zz, float dd ) : x( xx ), y( yy ), z( zz ), d( dd ) {}

		bool Valid() const ;
		unsigned int RequiredBufferSize() const;

		unsigned int WriteToBuffer( char* stream, unsigned int pos, unsigned int bufferLength ) const;
		void WriteToStream( std::ostream& stream ) const;

	};

	struct Face
	{
		unsigned int v1, v2, v3;
		unsigned int n1, n2, n3;
	};

	Plane SeparatingPlane( const std::vector<unsigned int>& vertexIndices, const std::vector<Vertex>& vertices );
	void CovarianceMatrix( const std::vector<unsigned int>& vertexIndices, const std::vector<Vertex>& vertices, double result[3][3], Vertex& mean ); 

}

#endif